package com.naiterui.ehp.bs.patient.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.domain.City;
import com.naiterui.ehp.bp.domain.Department;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bs.patient.dao.IDocumentParamDao;
import com.naiterui.ehp.bs.patient.repository.IApCityRepository;
import com.naiterui.ehp.bs.patient.repository.IApDepartmentRepository;
import com.naiterui.ehp.bs.patient.service.IParametersService;
import com.naiterui.ehp.bs.patient.utils.cache.BaseParamCacheUtil;
import com.naiterui.ehp.bs.patient.vo.CacheDataVO;
import com.naiterui.ehp.bs.patient.vo.CacheParamVO;
import com.naiterui.ehp.bs.patient.vo.common.CityVO;
import com.naiterui.ehp.bs.patient.vo.parameters.DepartmentVO;
import com.naiterui.ehp.bs.patient.vo.parameters.DocumentParamVO;
import com.naiterui.ehp.bs.patient.vo.parameters.ParamVO;
import com.naiterui.ehp.bs.patient.vo.parameters.ParametersVO;

/**
 * 系统参数业务实现
 *
 * @version 2015年6月24日 上午10:57:40 by Amber
 * @see IParametersService
 */
@Service
public class ApParametersServiceImpl implements IParametersService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ApParametersServiceImpl.class);

    @Autowired
    private IDocumentParamDao documentParamDao;

    @Autowired
    private IApDepartmentRepository departmentRepository;

    @Autowired
    private IApCityRepository cityRepository;

    @Override
    public ParametersVO getParameters() throws BusinessException {
        ParametersVO parametersVo = BaseParamCacheUtil.getBaseParamsFromRedis();
        if (parametersVo == null) {
            // 缓存没有，数据库获取
            parametersVo = this.getParametersFromDB();
            LOGGER.info("---------- getParameters INFO ; cache for params is empty load from DB");
        }
        return parametersVo;
    }

    @Override
    public ParametersVO refreshParameters() throws BusinessException {
        // 数据库读取最新配置信息
        ParametersVO parametersVo = this.getParametersFromDB();
        // 更新缓存
        BaseParamCacheUtil.setBaseParamsToRedis(parametersVo);

        return parametersVo;
    }

    /**
     * 数据库读取配置信息
     * ParametersService.getParametersFromDB()<BR>
     * <P>Author : Amber </P>
     * <P>Date : 2015年8月28日 </P>
     *
     * @return
     */
    private ParametersVO getParametersFromDB() {
        ParametersVO parametersVo = new ParametersVO();
        Map<Integer, List<ParamVO>> group = this.documentParamDao.getDocumentParams();
        DocumentParamVO documentParamVO = new DocumentParamVO();
        documentParamVO.setDefMedications(group.get(DocumentParamVO.DOCUMENT_PARAM_TYPE_MED));
        documentParamVO.setDefFamDisease(group.get(DocumentParamVO.DOCUMENT_PARAM_TYPE_FAM));
        documentParamVO.setDefPastDes(group.get(DocumentParamVO.DOCUMENT_PARAM_TYPE_PAST));
        documentParamVO.setDefWines(group.get(DocumentParamVO.DOCUMENT_PARAM_TYPE_WINE));
        // ***********设置档案参数
        parametersVo.setDocumParam(documentParamVO);

        // 一级科室
        List<DepartmentVO> firstList = this.buildFirstDepartments();
        if (firstList != null && !firstList.isEmpty()) {
            parametersVo.setFirstDepartments(firstList);
        }

        List<Department> departments = this.departmentRepository.findAllByParentIdIsNotNull();
        List<DepartmentVO> dsParams = new ArrayList<>();
        for (Department department : departments) {
            DepartmentVO paramVo = this.buildDepartmentVo(department);
            dsParams.add(paramVo);
        }
        // ************设置部门参数
        parametersVo.setDepartments(dsParams);

        // *********设置城市参数
        parametersVo.setCities(this.buildCityTree());

        return parametersVo;
    }

    /**
     * 构造城市树列表
     * ParametersService.findCityVo()
     *
     * @return
     *
     * @Author chenlin
     * @Date 2016年8月2日
     * @since 1.0.0
     */
    public List<DepartmentVO> buildFirstDepartments() {
        List<Department> allDepartments = this.departmentRepository.findAll();
        // 一级科室
        List<DepartmentVO> firstList = new ArrayList<>();
        if (allDepartments != null) {
            // 一级科室子科室
            Map<Integer, List<DepartmentVO>> firstMap = new HashMap<>();
            for (Department department : allDepartments) {
                if (department.getParentId() == 0) {
                    // 一级科室
                    DepartmentVO departmentVO = this.buildDepartmentVo(department);
                    firstList.add(departmentVO);
                } else {
                    // 二级科室
                    DepartmentVO departmentVO = this.buildDepartmentVo(department);
                    // 将该科室追加到对应一级科室下
                    List<DepartmentVO> childs = firstMap.get(department.getParentId());
                    if (childs == null) {
                        childs = new ArrayList<>();
                    }
                    // 添加到父级科室子科室列表
                    childs.add(departmentVO);
                    // 更新父级科室子科室
                    firstMap.put(department.getParentId(), childs);
                }
            }
            // 设置子科室
            for (DepartmentVO departmentVO : firstList) {
                departmentVO.setChilds(firstMap.get(departmentVO.getId()));
            }
        }
        return firstList;
    }

    /**
     * 构造城市树列表
     * ParametersService.findCityVo()
     *
     * @return
     *
     * @Author chenlin
     * @Date 2016年8月2日
     * @since 1.0.0
     */
    private List<CityVO> buildCityTree() {
        // 省VO列表
        List<CityVO> provinceVos = new ArrayList<>();
        // 省-市
        Map<Integer, CityVO> provinceMap = new HashMap<>();
        // 市-区
        Map<Integer, CityVO> cityMap = new HashMap<>();

        // 一级城市：省
        List<City> provinces = this.cityRepository.findByTypeAndAvailable(1, CommonConstant.AVAILABLE_VALID);
        for (City province : provinces) {
            CityVO privinceVo = this.buildCityVo(province);
            provinceVos.add(privinceVo);
            provinceMap.put(province.getId(), privinceVo);
        }
        // 二级城市：市
        List<City> cities = this.cityRepository.findByTypeAndAvailable(2, CommonConstant.AVAILABLE_VALID);
        for (City city : cities) {
            CityVO cityVo = this.buildCityVo(city);
            cityMap.put(city.getId(), cityVo);
            CityVO parent = provinceMap.get(city.getParentId());
            if (parent == null) {
                continue;
            }
            List<CityVO> childs = parent.getChilds();
            if (childs == null) {
                childs = new ArrayList<>();
                parent.setChilds(childs);
            }
            childs.add(cityVo);
        }

        // 三级城市：区
        List<City> areas = this.cityRepository.findByTypeAndAvailable(3, CommonConstant.AVAILABLE_VALID);
        for (City area : areas) {
            CityVO areaVo = this.buildCityVo(area);
            CityVO parent = cityMap.get(area.getParentId());
            if (parent == null) {
                continue;
            }
            List<CityVO> childs = parent.getChilds();
            if (childs == null) {
                childs = new ArrayList<>();
                parent.setChilds(childs);
            }
            childs.add(areaVo);
        }
        return provinceVos;
    }

    /**
     * 构造科室VO
     * ParametersService.buildDepartmentVo()<BR>
     * <P>Author : Amber </P>
     * <P>Date : 2015年9月10日 </P>
     *
     * @param department
     *
     * @return
     */
    private DepartmentVO buildDepartmentVo(Department department) {
        DepartmentVO departmentVo = new DepartmentVO();
        departmentVo.setId(department.getId());
        departmentVo.setName(department.getName());
        return departmentVo;
    }

    /**
     * 构造城市VO
     * ParametersService.buildCityVo()<BR>
     * <P>Author : Amber </P>
     * <P>Date : 2015年9月10日 </P>
     *
     * @param city
     *
     * @return
     */
    private CityVO buildCityVo(City city) {
        CityVO cityVo = new CityVO();
        cityVo.setId(city.getId());
        cityVo.setName(city.getName());
        cityVo.setParentId(city.getParentId().toString());
        return cityVo;
    }

    @Override
    public CacheDataVO getCacheData(Long cityVers, Long depVers) throws BusinessException {
        CacheDataVO data = new CacheDataVO();
        // 服务端城市数据版本
        long cacheCityVersion = BaseParamCacheUtil.getCacheCityVersion();
        // 城市数据客户端小于服务端,则返回
        if (cityVers == null || cityVers < cacheCityVersion) {
            CacheParamVO<CityVO> cityVo = new CacheParamVO<>();
            cityVo.setList(this.buildCityTree());
            cityVo.setVersion(cacheCityVersion);
            data.setCites(cityVo);
        }
        // 服务端部门数据版本
        long cacheDepartmentVersion = BaseParamCacheUtil.getCacheDepartmentVersion();
        // 城市数据客户端小于服务端,则返回
        if (depVers == null || depVers < cacheDepartmentVersion) {
            CacheParamVO<DepartmentVO> fristDeps = new CacheParamVO<>();
            fristDeps.setList(this.buildFirstDepartments());
            fristDeps.setVersion(cacheDepartmentVersion);
            data.setDepartments(fristDeps);
        }
        return data;
    }
}
